home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 34.zip
/
BS1 part 34
/
FredFish PD 314.adf
/
Zc
/
zcsrc.lzh
/
genstubs
/
genfunc.c
next >
Wrap
C/C++ Source or Header
|
1989-06-10
|
4KB
|
218 lines
/*
* Genfunc: Generates the assembler to put the C parameters on the
* stack to the required registers, and call the RKM procedure.
*
* Copyright 1988 by J.A. Lydiatt. Permission is given to freely
* distribute and/or modify this code for non-commmercial use.
* Maintenance Notes:
* 18Jun88 - V1.0 Created by Jal.
*/
#include "genstubs.h"
#define PERMREGS (~(0x0303))
#define REGA6 (0x4000)
typedef struct xdefnode {
struct xdefnode *next;
char name[1];
} XDEFNODE;
/*
* External variables:
*/
extern char base[]; /* ##base _SysBase for example */
extern int bias; /* ##bias 30 */
extern char Section[]; /* SECTION "<Section>",CODE */
extern FUNCINFO function; /* The current function. */
static XDEFNODE *xdeflist = NULL;
static FILE *fo;
/*
* genfunc: support code to generate the function.
*/
static int getrange( mask, frombit, tobit )
register unsigned int mask;
int frombit, tobit;
{
register int bit;
for (bit=frombit; bit <= tobit; ++bit ){
if ( !(mask & 1 << bit ))
break;
}
return --bit;
}
static int makelist( list, mask, frombit, tobit, idchar )
char list[];
register unsigned int mask;
int frombit, tobit;
char idchar;
{
int bit, endbit, nperm, endrange;
char tmp[32];
extern int sprintf();
extern char *strcat();
nperm = 0;
for ( bit=frombit; bit <= tobit; ++bit ){
if ( mask & 1 << bit ){
endrange = getrange( mask, bit, tobit );
if ( endrange > bit )
(void) sprintf( tmp, "/%c%d-%c%d",
idchar, bit % 8,
idchar, endrange % 8);
else
(void) sprintf( tmp, "/%c%d",
idchar, bit % 8 );
(void)strcat( list, tmp );
nperm += endrange - bit + 1;
bit = endrange;
}
}
return nperm;
}
static int getperm( mask, list )
unsigned int mask;
char *list;
{
char tmplist[64];
int nperm;
extern char *strcpy();
tmplist[0] = '\0';
nperm = makelist( tmplist, mask, 0, 7, 'D' );
nperm += makelist( tmplist, mask, 8, 15, 'A' );
if ( tmplist[0] != '\0' )
strcpy( list, &tmplist[1] );
else
list[0] = '\0';
return nperm;
}
static void gencomment( txt )
char *txt;
{
fprintf( fo, "* %s\n", txt );
}
static void gen( code, p1, p2, p3, p4 )
char *code;
long p1, p2, p3, p4;
{
putc( '\t', fo );
fprintf( fo, code, p1, p2, p3, p4);
putc( '\n', fo );
}
static void genlabel( label )
char *label;
{
(void)fputs( label, fo );
(void)putc( '\n', fo );
}
void genfunc()
{
int nperm; /* # Permanent registers used */
int permmask; /* Mask for permanent regs used. */
int offset;
int j;
FUNCINFO *f; /* Pointer to function info struct */
char permlist[128];
void assemble();
/*
* print the current line as a comment.
*/
f = &function;
sprintf( permlist, "ram:%s.a", &f->name[1] );
if ( (fo = fopen( permlist, "w")) == NULL ) {
fprintf( stderr, "Can't open: %s\n", permlist );
exit( 12 );
}
gencomment("");
gencomment( f->givenline );
gencomment( "" );
/*
* Start a new Section Name.
*/
gen( "SECTION\t%s,CODE", Section );
gen( "XDEF\t%s", f->name );
gen( "XREF\t%s", base );
genlabel( f->name );
/*
* Save any permanent registers used.
*/
nperm = getperm( f->regmask & PERMREGS | REGA6 , permlist );
if ( nperm )
gen( "MOVEM.L\t%s,-(a7)", permlist );
/*
* Generate a move instruction for each list.
*/
offset = 4 + nperm * 4;
for ( j=0; j<f->nlists; ++j ) {
gen( "MOVEM.L\t%d(A7),%s", offset, f->reglist[j] );
offset += f->nregs[j] * 4;
}
/*
* Generate the jump instruction, restore perm and exit.
*/
gen( "MOVEM.L\t%s,A6", base );
gen( "JSR\t%d(A6)", -bias );
if ( nperm )
gen( "MOVEM.L\t%(a7)+,%s", permlist );
gen( "RTS" );
gen( "END" );
fclose( fo );
assemble( &f->name[1] );
}
/*
* assemble a generated stub.
*/
#define ASSEMBLER "a68k"
#define AOPTION "-d"
static void
assemble( stub )
char *stub;
{
register XDEFNODE *p, *q;
char tmp1[128];
char tmp2[128];
int fexecl();
void unlink();
sprintf( tmp1, "ram:%s.a", stub);
sprintf( tmp2, "-oram:%s.o", stub);
printf( "%s %s %s %s\n", ASSEMBLER, AOPTION, tmp1, tmp2);
fexecl( ASSEMBLER,
AOPTION,
tmp1,
tmp2,
NULL);
unlink( tmp1 );
}